package com.mDigitalHealth.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.mDigitalHealth.R;
import com.mDigitalHealth.common.Utils;
import com.mDigitalHealth.network.DigitalHealthClient;
import com.mDigitalHealth.service.StepService;
import com.mDigitalHealth.settings.PedometerSettings;
import com.mDigitalHealth.thread.HourSaveThread;

public class SportActivity extends Activity implements OnClickListener {

	// private SharedPreferences mSharedPreferences;
	private static final String TAG = "SportActivity";

	public static String STEPS_CHANGED_ACTION = "com.name.bagi.levente.pedometer.steps";
	public static String METER_CHANGED_ACTION = "com.name.bagi.levente.pedometer.meter";
	public static String CALORY_CHANGED_ACTION = "com.name.bagi.levente.pedometer.calory";

	private ProgressBar mProgressBarWeek, mProgressBarDaily;
	private TextView mTextViewWeekTarget, mTextViewDailyTarget, mTextViewTodaySteps,
			mTextViewTodayMeter, mTextViewTodayCalorie;
	private TextView mTextViewLock, mTextViewUpload, mTextViewRunBackground;

	private SharedPreferences mSettings;
	private PedometerSettings mPedometerSettings;
	private Utils mUtils;

	private int mStepValue;
	private int mPaceValue;
	private float mDistanceValue;
	private float mSpeedValue;
	private int mCaloriesValue;
	private float mDesiredPaceOrSpeed;
	private int mMaintain;
	private boolean mIsMetric;
	private float mMaintainInc;
	private boolean mQuitting = false; // Set when user selected Quit from menu, can be used by
										// onPause, onStop, onDestroy

	/**
	 * True, when service is running.
	 */
	private boolean mIsRunning;

	SharedPreferences statePreference;
	SharedPreferences.Editor stateEditor;

	private ProgressDialog mProgressDialog;

	private ManualUploadHourStepsThread mManualUploadHourStepsThread;
	private float stepLength = 0.66f;

	// TODO: unite all into 1 type of message
	private StepService.ICallback mCallback = new StepService.ICallback() {
		public void stepsChanged(int value) {
			Log.i(TAG, "SportActivity-->stepService.ICallback-->setpsChanged--value=" + value);
			mHandler.sendMessage(mHandler.obtainMessage(STEPS_MSG, value, 0));
			stateEditor.putInt("steps", value).commit();
		}

		public void distanceChanged(float value) {
			/*mHandler.sendMessage(mHandler.obtainMessage(DISTANCE_MSG, (int)(value*1000), 0));
			stateEditor.putFloat("distance", (int)(value*1000)).commit();*/
		}

		public void caloriesChanged(float value) {
			mHandler.sendMessage(mHandler.obtainMessage(CALORIES_MSG, (int) (value), 0));
			stateEditor.putFloat("calories", (int) (value)).commit();
		}
	};

	private static final int STEPS_MSG = 1;
	private static final int DISTANCE_MSG = 3;
	private static final int CALORIES_MSG = 5;
	private static final int SHOW_PROGRESS_DIALOG = 7;
	private static final int DISSMISS_PROGRESS_DIALOG = 8;

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case STEPS_MSG:
				mStepValue = (int) msg.arg1;
				mTextViewTodaySteps.setText("" + mStepValue);
				int dailyPercent = (100 * mStepValue) / Utils.DAILY_TARGET_STEPS;
				mProgressBarDaily.setProgress(dailyPercent);
				mProgressBarWeek.setProgress(dailyPercent / 7);
				mTextViewDailyTarget.setText(dailyPercent + "%");
				mTextViewWeekTarget.setText(dailyPercent / 7 + "%");

				mDistanceValue = stepLength * mStepValue;
				if (mDistanceValue <= 0) {
					mTextViewTodayMeter.setText("0");
				} else {
					String str = String.valueOf(mDistanceValue);
					int dotIndex = str.indexOf(".");
					if (dotIndex > -1) {
						if (dotIndex + 3 < str.length()) {
							str = str.substring(0, str.indexOf(".") + 3);
						}
					}
					mTextViewTodayMeter.setText(str);
				}
				stateEditor.putFloat("distance", mDistanceValue).commit();
				break;
			case DISTANCE_MSG:
				mDistanceValue = ((int) msg.arg1) / 1000f;
				if (mDistanceValue <= 0) {
					mTextViewTodayMeter.setText("0");
				} else {
					/*try {
						mTextViewTodayMeter.setText(("" + (mDistanceValue + 0.000001f)).substring(0, 5));
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
					}*/
					String str = String.valueOf(mDistanceValue);
					int dotIndex = str.indexOf(".");
					if (dotIndex > -1) {
						if (dotIndex + 3 < str.length()) {
							str = str.substring(0, str.indexOf(".") + 3);
						}
					}
					mTextViewTodayMeter.setText(str);
				}
				break;
			case CALORIES_MSG:
				mCaloriesValue = msg.arg1;
				if (mCaloriesValue <= 0) {
					mTextViewTodayCalorie.setText("0");
				} else {
					mTextViewTodayCalorie.setText("" + (int) mCaloriesValue);
				}
				break;

			case SHOW_PROGRESS_DIALOG:
				if (mProgressDialog != null) {
					if (mProgressDialog.isShowing()) {
						mProgressDialog.dismiss();
					}
					mProgressDialog = null;
				}
				mProgressDialog = new ProgressDialog(SportActivity.this);
				mProgressDialog.setIndeterminate(true);
				mProgressDialog.setCancelable(false);
				mProgressDialog.setMessage("上传数据中...");
				mProgressDialog.show();
				break;

			case DISSMISS_PROGRESS_DIALOG:
				if (mProgressDialog != null) {
					if (mProgressDialog.isShowing()) {
						mProgressDialog.dismiss();
					}
					mProgressDialog = null;
				}
				break;

			default:
				super.handleMessage(msg);
			}
		}

	};

	StepBroadcastReceiver stepReceiver = null;
	MeterBroadcastReceiver meterReceiver = null;
	CaloryBroadcastReceiver caloryReceiver = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		this.setContentView(R.layout.sport_activity);
		mStepValue = 0;
		mPaceValue = 0;

		// mSharedPreferences = getSharedPreferences(Utils.PREFERENCE_NAME, Activity.MODE_PRIVATE);
		initViews();

		statePreference = getSharedPreferences("state", 0);
		stateEditor = statePreference.edit();

		mUtils = Utils.getInstance();

		IntentFilter filter = new IntentFilter(STEPS_CHANGED_ACTION);
		stepReceiver = new StepBroadcastReceiver();
		registerReceiver(stepReceiver, filter);

		filter = new IntentFilter(METER_CHANGED_ACTION);
		meterReceiver = new MeterBroadcastReceiver();
		registerReceiver(meterReceiver, filter);

		filter = new IntentFilter(CALORY_CHANGED_ACTION);
		caloryReceiver = new CaloryBroadcastReceiver();
		registerReceiver(caloryReceiver, filter);

	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		mSettings = PreferenceManager.getDefaultSharedPreferences(this);
		mPedometerSettings = new PedometerSettings(mSettings);

		// Read from preferences if the service was running on the last onPause
		mIsRunning = mPedometerSettings.isServiceRunning();

		// get step lengths
		stepLength = mPedometerSettings.getStepLength() / 100;

		// Start the service if this is considered to be an application start
		// (last onPause was long ago)
		if (!mIsRunning && mPedometerSettings.isNewStart()) {
			startStepService();
			bindStepService();
		} else if (mIsRunning) {
			bindStepService();
		}

		mPedometerSettings.clearServiceRunning();

		mMaintain = mPedometerSettings.getMaintainOption();
		if (mMaintain == PedometerSettings.M_PACE) {
			mMaintainInc = 5f;
			mDesiredPaceOrSpeed = (float) mPedometerSettings.getDesiredPace();
		} else if (mMaintain == PedometerSettings.M_SPEED) {
			mDesiredPaceOrSpeed = mPedometerSettings.getDesiredSpeed();
			mMaintainInc = 0.1f;
		}

	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();

		Log.i(TAG, "[ACTIVITY] onPause");
		/* if (mIsRunning) {
		     unbindStepService();
		 }
		 if (mQuitting) {
		     mPedometerSettings.saveServiceRunningWithNullTimestamp(mIsRunning);
		 }
		 else {
		     mPedometerSettings.saveServiceRunningWithTimestamp(mIsRunning);
		 }
		 savePaceSetting();*/
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		Log.i(TAG, "[ACTIVITY] onStop");
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.i(TAG, "[ACTIVITY] onDestroy");
		if (stepReceiver != null) {
			unregisterReceiver(stepReceiver);
			stepReceiver = null;
		}

		if (meterReceiver != null) {
			unregisterReceiver(meterReceiver);
			meterReceiver = null;
		}

		if (caloryReceiver != null) {
			unregisterReceiver(caloryReceiver);
			caloryReceiver = null;
		}

	}

	private void initViews() {
		mProgressBarWeek = (ProgressBar) findViewById(R.id.progress_week);
		mProgressBarDaily = (ProgressBar) findViewById(R.id.progress_daily);
		mTextViewWeekTarget = (TextView) findViewById(R.id.textview_week_target);
		mTextViewDailyTarget = (TextView) findViewById(R.id.textview_daily_target);
		mTextViewTodaySteps = (TextView) findViewById(R.id.textview_today_steps);
		mTextViewTodayMeter = (TextView) findViewById(R.id.textview_today_meter);
		mTextViewTodayCalorie = (TextView) findViewById(R.id.textview_today_calorie);
		mTextViewLock = (TextView) findViewById(R.id.textview_lock);
		mTextViewUpload = (TextView) findViewById(R.id.textview_upload);
		mTextViewRunBackground = (TextView) findViewById(R.id.textview_run_background);

		mTextViewLock.setOnClickListener(this);
		mTextViewUpload.setOnClickListener(this);
		mTextViewRunBackground.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.textview_lock:
			PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
			int wakeFlags = PowerManager.SCREEN_DIM_WAKE_LOCK;
			WakeLock wakeLock = pm.newWakeLock(wakeFlags, TAG);
			wakeLock.acquire();
			break;

		case R.id.textview_upload:
			if (mManualUploadHourStepsThread != null) {
				mManualUploadHourStepsThread = null;
			}
			mManualUploadHourStepsThread = new ManualUploadHourStepsThread();
			mManualUploadHourStepsThread.start();
			break;

		case R.id.textview_run_background:
			resetValues(false);
			mQuitting = false;
			finish();
			break;

		default:
			break;
		}
	}

	private void savePaceSetting() {
		mPedometerSettings.savePaceOrSpeedSetting(mMaintain, mDesiredPaceOrSpeed);
	}

	private StepService mService;

	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			mService = ((StepService.StepBinder) service).getService();
			// Log.i(TAG, "SportActivity---mConnection--->onServiceConnected");
			mService.registerCallback(mCallback);
			mService.reloadSettings();

		}

		public void onServiceDisconnected(ComponentName className) {
			mService = null;
		}
	};

	private void startStepService() {
		if (!mIsRunning) {
			Log.i(TAG, "[SERVICE] Start");
			mIsRunning = true;
			startService(new Intent(SportActivity.this, StepService.class));
		}
	}

	private void bindStepService() {
		// Log.i(TAG, "[SERVICE] Bind");
		getApplicationContext().bindService(new Intent(SportActivity.this, StepService.class),
				mConnection, Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);
	}

	private void unbindStepService() {
		// Log.i(TAG, "[SERVICE] Unbind");
		getApplicationContext().unbindService(mConnection);
	}

	private void stopStepService() {
		Log.i(TAG, "[SERVICE] Stop");
		if (mService != null) {
			Log.i(TAG, "[SERVICE] stopService");
			stopService(new Intent(SportActivity.this, StepService.class));
		}
		mIsRunning = false;
	}

	private static final int MENU_PAUSE = 1;
	private static final int MENU_RESUME = 2;
	private static final int MENU_RESET = 3;

	private static final int MENU_SETTINGS = 8;
	private static final int MENU_QUIT = 9;
	private static final int MENU_RUN_BACKGROUND = 11;

	/* Creates the menu items */
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		/*if (mIsRunning) {
			menu.add(0, MENU_PAUSE, 0, R.string.pause).setIcon(
					android.R.drawable.ic_media_pause).setShortcut('1', 'p');
		} else {
			menu.add(0, MENU_RESUME, 0, R.string.resume).setIcon(
					android.R.drawable.ic_media_play).setShortcut('1', 'p');
		}
		menu.add(0, MENU_RESET, 0, R.string.reset).setIcon(
				android.R.drawable.ic_menu_close_clear_cancel).setShortcut('2',
				'r');
		menu.add(0, MENU_SETTINGS, 0, R.string.settings).setIcon(
				android.R.drawable.ic_menu_preferences).setShortcut('8', 's')
				.setIntent(new Intent(this, Settings.class));*/
		/*menu.add(0, MENU_RUN_BACKGROUND, 0, R.string.settings).setIcon(
				android.R.drawable.ic_menu_preferences).setShortcut('8', 's')
				.setIntent(new Intent(this, Settings.class));
		menu.add(0, MENU_QUIT, 0, R.string.quit).setIcon(
				android.R.drawable.ic_lock_power_off).setShortcut('9', 'q');*/
		menu.add(0, MENU_RUN_BACKGROUND, 0, R.string.run_background);
		menu.add(0, MENU_QUIT, 0, R.string.quit);
		return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		/*case MENU_PAUSE:
			unbindStepService();
			stopStepService();
			return true;
		case MENU_RESUME:
			startStepService();
			bindStepService();
			return true;*/
		/*case MENU_RESET:
			resetValues(true);
			return true;*/
		case MENU_RUN_BACKGROUND:
			// resetValues(false);
			mQuitting = false;
			finish();
			return true;
		case MENU_QUIT:
			resetValues(false);
			unbindStepService();
			stopStepService();
			mQuitting = true;
			// finish();
			Utils.quitApplication(SportActivity.this);
			return true;
		}
		return false;
	}

	private void resetValues(boolean updateDisplay) {
		/*if (mService != null && mIsRunning) {
			mService.resetValues();
		} else {*/
		// mTextViewTodaySteps.setText("0");
		// mPaceValueView.setText("0");
		// mTextViewTodayMeter.setText("0");
		// mSpeedValueView.setText("0");
		// mTextViewTodayCalorie.setText("0");

		if (updateDisplay) {
			stateEditor.putInt("steps", 0);
			stateEditor.putInt("pace", 0);
			stateEditor.putFloat("distance", 0);
			stateEditor.putFloat("speed", 0);
			stateEditor.putFloat("calories", 0);
			stateEditor.commit();
		} else {
			stateEditor.putInt("steps", Integer.parseInt(mTextViewTodaySteps.getText().toString()));
			stateEditor.putInt("pace", 0);
			stateEditor.putFloat("distance",
					Float.parseFloat(mTextViewTodayMeter.getText().toString()));
			stateEditor.putFloat("speed", 0);
			stateEditor.putFloat("calories",
					Float.parseFloat(mTextViewTodayCalorie.getText().toString()));
			stateEditor.commit();
		}

		/*}*/
	}

	public class StepBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			int value = 0;
			if (STEPS_CHANGED_ACTION.equalsIgnoreCase(action)) {
				value = intent.getExtras().getInt("VALUE", 0);
				mHandler.sendMessage(mHandler.obtainMessage(STEPS_MSG, value, 0));
			}
			// 终止广播，在这里我们可以稍微处理，根据用户输入的号码可以实现短信防火墙。
			// abortBroadcast();
		}

	}

	public class MeterBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			int value = 0;
			if (METER_CHANGED_ACTION.equalsIgnoreCase(action)) {
				value = (int) (intent.getExtras().getFloat("VALUE", 0) * 1000);
				mHandler.sendMessage(mHandler.obtainMessage(DISTANCE_MSG, value, 0));
			}
			// 终止广播，在这里我们可以稍微处理，根据用户输入的号码可以实现短信防火墙。
			// abortBroadcast();
		}

	}

	public class CaloryBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			int value = 0;
			if (CALORY_CHANGED_ACTION.equalsIgnoreCase(action)) {
				value = (int) intent.getExtras().getFloat("VALUE", 0);
				mHandler.sendMessage(mHandler.obtainMessage(CALORIES_MSG, value, 0));
			}
			// 终止广播，在这里我们可以稍微处理，根据用户输入的号码可以实现短信防火墙。
			// abortBroadcast();
		}

	}

	private class ManualUploadHourStepsThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			mHandler.sendEmptyMessage(SHOW_PROGRESS_DIALOG);
			SharedPreferences mSharedPreferences = PreferenceManager
					.getDefaultSharedPreferences(SportActivity.this);
			String name = mSharedPreferences.getString(Utils.PREFERENCE_KEY_USER_NAME, "");
			DigitalHealthClient.uploadUserHourStepInfo(SportActivity.this, name);
			try {
				extracted();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			mHandler.sendEmptyMessage(DISSMISS_PROGRESS_DIALOG);

		}

		private void extracted() throws InterruptedException {
			this.sleep(2000);
		}

	}

	private class saveStepsThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();

			SharedPreferences mState = getSharedPreferences("state", 0);

			SharedPreferences.Editor mStateEditor = mState.edit();
			int mSteps = mState.getInt("steps", 0);
			// System.out.println("**today steps="+todaySteps+",steps="+steps);
			new HourSaveThread(SportActivity.this, mState, mStateEditor, mSteps);

		}

	}

}
